/*
-----------------------------------------------------------------------------
This source file is part of Labor3D
(Labor 3D Graphics Engine)

Copyright (c) 2009-2020 Rock Mao
* creator : Rock Mao
* created : 2009-5-4   14:52
* filename: LaborPlugin.h
-----------------------------------------------------------------------------
*/

#ifndef __LABORPLUGIN_H__
#define __LABORPLUGIN_H__
#include "../LaborCoreDef.h"

NAMESPACE_LABOR3D_BEGIN

enum  ePluginType
{
	ePT_Renderer,
	ePT_Platform,
	ePT_Script,
	ePT_Subsystem,
	ePT_ObjectCreator,
};

enum 
{
	eBuild_Debug       = 0x00001,
	eBuild_Unicode     = 0x00002,
	eBuild_Static      = 0x00004,
	eBuild_MultiThread = 0x00008
};

struct slPluginInfo 
{
	char        m_Name[32];
	char        m_Description[256];
	int         m_ID;
	ePluginType m_Type;
	int         m_Build;
public:
	bool bCheckBuild(int buildFlag) {return 0 != (m_Build & buildFlag) ; }
};

class CLPlugin
{
protected:
	slPluginInfo        m_pluginInfo;
	char               m_PathName[1024];
	char               m_FileName[256];
	void*              m_dllHanle;
public:
	CLPlugin() {}
	virtual ~CLPlugin() {}
	/** Get the name of the plugin. 
	@remarks An implementation must be supplied for this method to uniquely
	identify the plugin.
	*/
	virtual const CLString& getName() const = 0;
	/** Perform the plugin initial installation sequence. 
	@remarks An implementation must be supplied for this method. It must perform
	the startup tasks necessary to install any rendersystem customisations 
	or anything else that is not dependent on system initialisation, ie
	only dependent on the core of Ogre. It must not perform any
	operations that would create rendersystem-specific objects at this stage,
	that should be done in initialise().
	*/
	virtual void install() = 0;
	/** Perform any tasks the plugin needs to perform on full system
	initialisation.
	@remarks An implementation must be supplied for this method. It is called 
	just after the system is fully initialised (either after Root::initialise
	if a window is created then, or after the first window is created)
	and therefore all rendersystem functionality is available at this
	time. You can use this hook to create any resources which are 
	dependent on a rendersystem or have rendersystem-specific implementations.
	*/
	virtual void initialise() = 0;
	/** Perform any tasks the plugin needs to perform when the system is shut down.
	@remarks An implementation must be supplied for this method.
	This method is called just before key parts of the system are unloaded, 
	such as rendersystems being shut down. You should use this hook to free up 
	resources and decouple custom objects from the OGRE system, whilst all the
	instances of other plugins (e.g. rendersystems) still exist.
	*/
	virtual void destory() = 0;
	/** Perform the final plugin uninstallation sequence. 
	@remarks An implementation must be supplied for this method. It must perform
	the cleanup tasks which haven't already been performed in shutdown()
	(e.g. final deletion of custom instances, if you kept them around incase
	the system was reinitialised). At this stage you cannot be sure what other
	plugins are still loaded or active. It must therefore not perform any
	operations that would reference any rendersystem-specific objects - those
	should have been sorted out in the 'shutdown' method.
	*/
	virtual void uninstall() = 0;
	virtual void getPluginInfo(slPluginInfo* pluginfo) = 0;
	const slPluginInfo& info(){return m_pluginInfo; }
	void                getFileName( std::string &file_name) { file_name = m_FileName; }

};

NAMESPACE_LABOR3D_END

#endif